<template>
	<Page title="添加出差记录" style="height: 100vh; padding-bottom: 10px">
		<template #body>
			<!-- ---------------------出差日期--------------------- -->
			<van-calendar :min-date="dayjs().subtract(1, 'year').toDate()" :max-date="dayjs().toDate()"
				:default-date="dayjs().toDate()" v-model:show="main.showCalendar" @confirm="onCalendarConfirm" />
			<van-cell title="出差日期" is-link :value="main.travelInfo.travelDate" @click="main.showCalendar = true">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-calendar-day"></i>
					</div>
				</template>
			</van-cell>

			<!-- ---------------------出差地址--------------------- -->
			<van-popup v-model:show="main.showAddressPopup" round position="bottom">
				<van-cascader v-model="main.cascaderValue" title="请选择出差地址" :options="main.addressLibrary"
					@close="main.showAddressPopup = false" @finish="onCascaderFinish" />
			</van-popup>
			<van-cell title="出差地址" is-link :value="main.travelInfo.travelAddress" @click="main.showAddressPopup = true">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-map-marked-alt"></i>
					</div>
				</template>
			</van-cell>

			<!-- ---------------------出差人员--------------------- -->
			<van-action-sheet v-model:show="main.showActionSheet" title="出差人员">
				<div class="active-sheet-content">
					<van-grid :column-num="4" :gutter="10" square>
						<van-grid-item v-for="value in main.peopleLibrary" :key="value" icon="user-circle-o"
							:text="value" @click="selectTravelPeople(value)"
							:icon-color="peopleIsActive(value) ? '#1989fa' : ''"
							:class="{ active: peopleIsActive(value) }"></van-grid-item>
					</van-grid>
				</div>
			</van-action-sheet>
			<van-cell title="出差人员" is-link :value="main.travelInfo.travelPeople.map(map => map.name).join(',')"
				@click="main.showActionSheet = true" value-class="travelPeopleStyle">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-user-friends"></i>
					</div>
				</template>
			</van-cell>

			<van-cell-group inset>
				<van-cell :title="item.name" v-for="(item, index) in main.travelInfo.travelPeople" :key="index"
					title-class="haveMealsClass">
					<template #value>
						<van-checkbox-group v-model="item.mealsSelected" direction="horizontal">
							<van-checkbox :name="item.id" v-for="(item, idx) in haveMeals" :key="idx">
								{{ item.label }}
							</van-checkbox>
						</van-checkbox-group>
					</template>
				</van-cell>
			</van-cell-group>

			<!-- ---------------------经办人员--------------------- -->
			<van-action-sheet v-model:show="main.showHandledBySheet" title="经办人员">
				<div class="active-sheet-content">
					<van-grid :column-num="4" :gutter="10" square>
						<van-grid-item v-for="value in main.peopleLibrary" :key="value" icon="user-circle-o"
							:text="value" @click="selectHandledBy(value)"
							:icon-color="handledByIsActive(value) ? '#1989fa' : ''"
							:class="{ active: handledByIsActive(value) }"></van-grid-item>
					</van-grid>
				</div>
			</van-action-sheet>
			<van-cell title="经办人员" is-link :value="main.travelInfo.handledBy" @click="main.showHandledBySheet = true"
				value-class="travelPeopleStyle">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-user-tie"></i>
					</div>
				</template>
			</van-cell>

			<!-- ---------------------是否公务用车--------------------- -->
			<van-cell clickable title="是否公务用车" @click="main.travelInfo.officialCars = !main.travelInfo.officialCars">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-car-side"></i>
					</div>
				</template>
				<template #right-icon>
					<van-checkbox v-model="main.travelInfo.officialCars" @click.stop />
				</template>
			</van-cell>

			<!-- ---------------------包干交通费--------------------- -->
			<van-action-sheet v-model:show="main.showCarFarePopup" title="包干交通费">
				<div class="actionSheepContent">
					<van-radio-group v-model="main.lumpSumCarFare">
						<van-cell-group inset>
							<van-cell :title="item.address" clickable @click="main.lumpSumCarFare = item.id"
								v-for="item in main.lumpSumCarFareLibrary" :key="item.id">
								<template #value>¥{{ item.fare }}</template>
								<template #icon>

								</template>
								<template #right-icon>
									<van-radio :name="item.id" />
								</template>
							</van-cell>
						</van-cell-group>
					</van-radio-group>
				</div>
			</van-action-sheet>
			<van-cell clickable is-link title="包干交通费" :value="main.lumpSumCarFareLibrary.find(it => it.id == main.lumpSumCarFare)
				?.fare || 0
				" v-if="!main.travelInfo.officialCars" @click="main.showCarFarePopup = !main.showCarFarePopup">
				<template #icon>
					<div class="icon-card">
						<i class="fas fa-bus"></i>
					</div>
				</template>
			</van-cell>

			<!-- ---------------------出差事由--------------------- -->
			<van-cell-group>
				<van-field v-model="main.travelInfo.travelReason" rows="2" autosize type="textarea" maxlength="30"
					placeholder="请输入出差事由..." show-word-limit clearable />
			</van-cell-group>

			<!-- ---------------------添加按钮--------------------- -->
			<van-row :style="`margin:${usePxTransform(10)}`">
				<van-col offset="6" span="12">
					<van-button plain type="primary" block size="small" @click="addRecord">
						添加记录
					</van-button>
				</van-col>
			</van-row>

			<van-divider :style="{ color: '#1989fa', borderColor: '#1989fa' }">
				可选项，自定义费用将覆盖系统费用
			</van-divider>

			<van-collapse v-model="customizeBox">
				<van-collapse-item title="自定义差旅费" name="1">
					<van-cell-group>
						<!-- 允许输入数字，调起带符号的纯数字键盘 -->
						<van-field v-model="main.customizeAmount" type="number" readonly disabled label="差旅费合计">
							<template #right-icon>
								<van-icon name="question-o" @click="showCustomizeAmountTip" />
							</template>
						</van-field>
					</van-cell-group>

					<van-cell-group>
						<van-cell v-for="(item, index) in main.travelInfo.travelPeople" :key="index"
							title-class="haveMealsClass">
							<template #value>
								<van-cell-group inset>
									<van-field v-model="item.myTravelExpenses" required clearable type="number"
										:label="item.name" />
								</van-cell-group>
							</template>
						</van-cell>
					</van-cell-group>

					<van-cell-group>
						<van-cell>
							<van-row gutter="20">
								<van-col span="12" style="text-align: center">
									<van-button plain size="small" block type="primary" @click="saveCustomizeAmountBtn">
										保存
									</van-button>
								</van-col>
								<van-col span="12" style="text-align: center">
									<van-button plain size="small" block type="success"
										@click="resetCustomizeAmountBtn">
										重置
									</van-button>
								</van-col>
							</van-row>
						</van-cell>
					</van-cell-group>

					<van-cell-group>
						<van-field v-model="main.travelInfo.notes" rows="2" autosize type="textarea" maxlength="60"
							placeholder="自定义差旅各人员费用详情..." show-word-limit clearable />
					</van-cell-group>
				</van-collapse-item>
			</van-collapse>
		</template>
	</Page>
</template>

<script setup lang="ts" name="AddTravelRecord">
import AddTravelRecordClass, {
	haveMeals,
	TravelPerson,
} from "./AddTravelRecord.ts"
import dayjs from "dayjs"
import { reactive, ref } from "vue"
import { DB } from "@/assets/global"
import { showDialog, showToast } from "vant"
import * as indexedDB from "@/utility/indexedDB.ts"
import { nanoid } from "nanoid"
import usePxTransform from "@hooks/usePxTransform"
import useDemoStore, { TAddress } from "@/store/TravelRecordLibraryStore.ts"
import _ from "lodash"

const main = reactive(new AddTravelRecordClass())
const store = useDemoStore()
main.peopleLibrary = store.PeopleLibrary || []
main.addressLibrary = store.AddressLibrary || []
main.lumpSumCarFareLibrary = store.LumpSumCarFareLibrary || []
const customizeBox = ref(["0"])

const selectHandledBy = (value: string) => {
	main.travelInfo.handledBy = value
	main.showHandledBySheet = false
}

const saveCustomizeAmountBtn = () => {
	let sum = 0
	main.travelInfo.travelPeople.forEach(people => {
		sum += Number(people.myTravelExpenses)
	})
	main.customizeAmount = sum
	showToast("保存成功！")
}

const resetCustomizeAmountBtn = () => {
	main.travelInfo.travelPeople.forEach(people => {
		people.myTravelExpenses = 0
	})
	main.customizeAmount = 0
	showToast("重置成功！")
}

const showCustomizeAmountTip = () => {
	showDialog({ message: "自定义差旅将覆盖原有差旅费。" })
}

const handledByIsActive = (handledBy: string) => {
	return handledBy == main.travelInfo.handledBy
}

const peopleIsActive = (people: string) => {
	return main.travelInfo.travelPeople.some(person => person.name === people)
}

const selectTravelPeople = (people: string) => {
	// 查找是否已存在该人名
	const personIndex = main.travelInfo.travelPeople.findIndex(
		person => person.name === people
	)

	if (personIndex === -1) {
		// 如果不存在，添加新人
		let obj: TravelPerson = {
			name: people,
			myTravelExpenses: 0,
			mealsSelected: [],
		}
		main.travelInfo.travelPeople.push(obj)
	} else {
		// 如果已存在，删除该人
		main.travelInfo.travelPeople.splice(personIndex, 1)
	}
}

const onCascaderFinish = ({
	selectedOptions,
}: {
	selectedOptions: TAddress[]
}) => {
	main.showAddressPopup = false
	main.travelInfo.travelAddress = selectedOptions
		.map(list => list.text)
		.join("/")
}

const onCalendarConfirm = (value: Date) => {
	main.showCalendar = false
	main.travelInfo.travelDate = dayjs(value).format("YYYY/MM/DD")
}

const findTravelCost = (array: TAddress[], value: string) => {
	for (let parent of array) {
		if (parent.children) {
			for (let child of parent.children) {
				if (child.value == value) {
					return { parent, child }
				}
			}
		} else {
			return { parent, undefined }
		}
	}
	return null // 如果没有找到，返回 null
}

const calcTravelExpenses = () => {
	if (main.customizeAmount != 0) {
		return main.customizeAmount
	}
	// 获取对应出差地的伙食费和公杂费
	const { child, parent } =
		findTravelCost(main.addressLibrary, main.cascaderValue) || {}

	// 公杂费（既交通费）标准
	const baseTransportationExpenses = parent?.cost ?? 0
	// 派车公杂费减半
	const transportationExpenses = main.travelInfo.officialCars
		? baseTransportationExpenses / 2
		: baseTransportationExpenses

	// 未派车的包干费用计算
	let lumpSumCarFare = 0
	if (!main.travelInfo.officialCars) {
		lumpSumCarFare = Number(
			main.lumpSumCarFareLibrary.find(it => it.id == main.lumpSumCarFare)
				?.fare || 0
		)
	}

	// 伙食费标准
	const boardExpenses = child?.cost ?? 0
	// 最终计算出的所有人差旅合计
	let allPeopleTeavelExpenses = 0
	main.travelInfo.travelPeople = main.travelInfo.travelPeople.map(people => {
		const meals = people.mealsSelected.reduce((sum, mealId) => {
			const meal = haveMeals.find(m => m.id === mealId)
			return sum + (meal?.discount || 0)
		}, 0)
		let everyPeopleTeavelExpenses = Math.round(
			boardExpenses * (1 - meals) + transportationExpenses + lumpSumCarFare
		)
		allPeopleTeavelExpenses += everyPeopleTeavelExpenses
		return {
			...people,
			myTravelExpenses: everyPeopleTeavelExpenses,
		}
	})

	return allPeopleTeavelExpenses
}

const clearSaveData = () => {
	main.travelInfo = new AddTravelRecordClass().travelInfo
	main.cascaderValue = ""
	main.lumpSumCarFare = ""
	main.customizeAmount = 0
}

const validateForm = () => {
	let travelInfo = main.travelInfo
	if (travelInfo.travelDate == "") return "出差日期\n不能为空"
	if (travelInfo.travelAddress == "") return "出差地址\n不能为空"
	if (travelInfo.travelPeople.length == 0) return "出差人员\n不能为空"
	if (travelInfo.handledBy == "") return "经办人员\n不能为空"
	if (travelInfo.travelReason == "") return "出差事由\n不能为空"
	return -1
}

const addRecord = async () => {
	const valRes = validateForm()
	if (valRes != -1) {
		showToast({ type: "fail", message: valRes })
		return
	}
	main.travelInfo.id = nanoid(8)
	main.travelInfo.travelExpenses = calcTravelExpenses()
	main.travelInfo.createDate = dayjs().format("YYYY/MM/DD HH:mm:ss")
	await indexedDB.add(DB.store.TravelRecord.name, _.cloneDeep(main.travelInfo))
	showToast({
		type: "success",
		message: `保存成功！`,
	})
	clearSaveData()
}
</script>

<style scoped lang="scss">
::v-deep(.body) {
	padding: 0;
}

.cell-icon {
	color: #1989fa !important;
	font-size: 15px;
	margin-right: 3px;
}


.icon-card {
	text-align: center;
	width: 20px;
	height: 20px;
	margin-right: 7px;

	i {
		font-size: 16px;
		color: #1989fa;
	}
}

::v-deep(.van-popup--bottom) {
	height: 65%;
}

.active-sheet-content {
	padding: 16px 16px 48px;

	// 激活项样式 - 简约版
	::v-deep(.van-grid-item__text) {
		margin: auto;
	}

	.active {
		::v-deep(.van-grid-item__content) {
			border: 1px solid #1989fa;
		}

		::v-deep(.van-grid-item__text) {
			color: #1989fa;
		}
	}


}

.travelPeopleStyle {
	min-width: none;
	white-space: nowrap;
}

::v-deep(.haveMealsClass) {
	max-width: 40% !important;
}

.actionSheepContent {
	padding-bottom: 160px;

	::v-deep(.van-cell__value) {
		display: flex;
		flex-direction: row-reverse;
		align-items: center;
		color: $error-color;
		padding: 0 10px;
	}
}
</style>
